package com.ws.shop.util;

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class BOSSecurity {

	private static String key = "295";

	private static int length = 64;

	public static String encode64(String src) throws Exception {
		int l = src.length();
		if (l > length / 2) {
			throw new Exception("The length of encode string must less than "
					+ length / 2);
		}
		int dest = length / 2;
		byte[] tmp = new byte[dest];
		byte[] srcByte = src.getBytes();

		for (int i = 0; i < tmp.length; i++) {
			tmp[i] = (byte) 0;
		}

		int head = 0;
		int tail = dest - 1;
		for (int i = l - 1; i >= 0; i--) {
			int take = getRandom(head, tail - i);
			tmp[take] = srcByte[l - i - 1];
			head = take + 1;
		}
		for (int i = 0; i < tmp.length; i++) {
			if (tmp[i] == 0) {
				int take = (int) (Math.random() * 31);
				tmp[i] = (byte) take;
			}
		}
		src = new String(tmp);

		byte[] b = src.getBytes();
		byte[] kb = key.getBytes();
		int j = 0;
		for (int i = 0; i < b.length; i++) {
			if (j != 0 && j % kb.length == 0)
				j = 0;
			if ((b[i] + kb[j]) > 127)
				b[i] = (byte) (b[i] + kb[j] - 127);
			else
				b[i] += kb[j];
			j++;
		}
		String r = "";
		String ts = "";
		for (int i = 0; i < b.length; i++) {
			ts = Integer.toHexString(b[i]);
			if (ts.length() < 2) {
				ts = "0" + ts;
			}
			r += ts;
		}
		return r;
	}

	public static String decode64(String src) throws Exception {
		int srcLength = src.length();
		if (srcLength != length) {
			throw new Exception("The length of decode string must be " + length);
		}
		int l = length / 2;
		byte[] tmp = new byte[l];
		String h = null;
		for (int i = 0; i < l; i++) {
			h = src.substring(i * 2, (i + 1) * 2);
			int r = Integer.decode("#" + h).intValue();
			tmp[i] = (byte) r;
		}
		src = new String(tmp);		
		byte[] b = src.getBytes();
		byte[] kb = key.getBytes();

		int j = 0;
		for (int i = 0; i < b.length; i++) {
			if (j != 0 && j % kb.length == 0)
				j = 0;
			if ((b[i] - kb[j]) < 0)
				b[i] = (byte) (b[i] - kb[j] + 127);
			else
				b[i] -= kb[j];
			j++;
		}

		int n = 0;
		for (int i = 0; i < b.length; i++) {
			if (b[i] > 31) {
				n++;
			}
		}
		byte[] db = new byte[n];
		n = 0;
		for (int i = 0; i < b.length; i++) {
			if (b[i] > 31) {
				db[n] = b[i];
				n++;
			}
		}

		String r = new String(db);
		return r;
	}

	private static int getRandom(int begin, int end) {
		int result = 0;
		result = (int) (Math.random() * (end - begin) + begin);
		return result;
	}

	private static int STEP_KEY = 3;

	public static String encode(String src) {
		String r = "";
		byte[] b = src.getBytes();
		String ts = null;
		for (int i = 0; i < b.length; i++) {
			b[i] -= STEP_KEY;
			ts = Integer.toHexString(b[i]);
			if (ts.length() < 2) {
				ts = "0" + ts;
			}
			r += ts;
		}
		return r;
	}

	public static String decode(String src) {
		int srcLength = src.length();
		int l = srcLength / 2;
		byte[] tmp = new byte[l];
		String h = null;
		for (int i = 0; i < l; i++) {
			h = src.substring(i * 2, (i + 1) * 2);
			int r = Integer.decode("#" + h).intValue();
			tmp[i] = (byte) (r + STEP_KEY);
		}
		String r = new String(tmp);
		return r;
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		while (true) {
			System.out.println("Please select:");
			System.out.println("1  encode");
			System.out.println("2  decode");
			System.out.println("3  encode64");
			System.out.println("4  decode64");
			System.out.println("Press any other key to quit.");
			String select = in.readLine();
			if (select.equals("1")) {
				System.out.println("Input string:");
				String encodeStr = in.readLine();
				System.out.println(BOSSecurity.encode(encodeStr));
				continue;
			} else if (select.equals("2")) {
				System.out.println("Input string:");
				String decodeStr = in.readLine();
				System.out.println(BOSSecurity.decode(decodeStr));
				continue;
			} else if (select.equals("3")) {
				System.out.println("Input string:");
				String encodeStr = in.readLine();
				try {
					System.out.println(BOSSecurity.encode64(encodeStr));
				} catch (Exception e) {
					System.out.println(e.getMessage());
				}
				continue;
			} else if (select.equals("4")) {
				System.out.println("Input string:");
				String decodeStr = in.readLine();
				try {
					System.out.println(BOSSecurity.decode64(decodeStr));
				} catch (Exception e) {
					System.out.println(e.getMessage());
				}
				continue;
			} else
				break;
		}
	}

}
